/**
 * 
 */
package co.edu.eam.iso.evaluator;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import co.edu.eam.iso.enums.CharacteristicEnum;
import co.edu.eam.iso.enums.SubCharacteristicEnum;
import co.edu.eam.iso.evaluated.CharacteristicEvaluated;
import co.edu.eam.iso.evaluated.MetricEvaluated;
import co.edu.eam.iso.evaluated.ProductEvaluated;
import co.edu.eam.iso.evaluated.SubCharacteristicEvaluated;
import co.edu.eam.iso.util.BigDecimalUtil;

/**
 * @author Giovanny Ramirez Blandon
 * @version 1.0
 */
public class Evaluator {

	public ProductEvaluated evaluateProduct(
			Map<CharacteristicEnum, Characteristic> characteristics) {
		Map<CharacteristicEnum, CharacteristicEvaluated> characteristicsEvaluated = new HashMap<CharacteristicEnum, CharacteristicEvaluated>();
		BigDecimal productQuality = BigDecimal.ZERO;

		for (Entry<CharacteristicEnum, Characteristic> characteristic : characteristics
				.entrySet()) {
			CharacteristicEvaluated characteristicEvaluated = evaluateCharacteristic(characteristic
					.getValue());

			characteristicsEvaluated.put(characteristic.getKey(),
					characteristicEvaluated);

			productQuality = BigDecimalUtil.add(productQuality,
					characteristicEvaluated.getQualityVStotal());
		}
		
		ProductEvaluated productEvaluated = new ProductEvaluated();
		productEvaluated.setCharacteristics(characteristicsEvaluated);
		productEvaluated.setQuality(productQuality);

		return productEvaluated;
	}
	
	private CharacteristicEvaluated evaluateCharacteristic(
			Characteristic characteristic) {
		Map<SubCharacteristicEnum, SubCharacteristicEvaluated> subCharacteristicsEvaluated = new HashMap<SubCharacteristicEnum, SubCharacteristicEvaluated>();
		BigDecimal qualityCharacteristic = BigDecimal.ZERO;

		for (Entry<SubCharacteristicEnum, SubCharacteristic> subCharacteristic : characteristic
				.getSubcharacteristics().entrySet()) {
			List<MetricEvaluated> metricsEvaluated = new ArrayList<MetricEvaluated>();
			BigDecimal qualitySubCharacteristic = BigDecimal.ZERO;
			BigDecimal average = BigDecimalUtil.divide(subCharacteristic
					.getValue().getWeight(), BigDecimalUtil
					.wrap(subCharacteristic.getValue().getMetrics().size()));
			
			for (Metric metric : subCharacteristic.getValue().getMetrics()) {
				BigDecimal qualityMetric = BigDecimalUtil.ruleOfThree(
						BigDecimalUtil.wrap(metric.getScale().getValue()),
						BigDecimalUtil.FIVE, average);				
				
				MetricEvaluated metricEvaluated = new MetricEvaluated();
				metricEvaluated.setMetric(metric);
				metricEvaluated.setQuality(qualityMetric);
				metricEvaluated.setAverage(average);
				metricsEvaluated.add(metricEvaluated);

				qualitySubCharacteristic = BigDecimalUtil.add(
						qualitySubCharacteristic, qualityMetric);
			}

			SubCharacteristicEvaluated subCharacteristicEvaluated = new SubCharacteristicEvaluated();
			subCharacteristicEvaluated.setSubCharacteristic(subCharacteristic.getValue());
			subCharacteristicEvaluated.setQuality(qualitySubCharacteristic);
			subCharacteristicEvaluated.setMetrics(metricsEvaluated);
			
			subCharacteristicsEvaluated.put(subCharacteristic.getKey(),
					subCharacteristicEvaluated);

			qualityCharacteristic = BigDecimalUtil.add(qualityCharacteristic,
					qualitySubCharacteristic);
		}
		
		BigDecimal qualityVStotal = BigDecimalUtil.ruleOfThree(
				characteristic.getWeight(), BigDecimalUtil.HUNDRED,
				qualityCharacteristic);		

		CharacteristicEvaluated characteristicEvaluated = new CharacteristicEvaluated();
		characteristicEvaluated.setSubCharacteristics(subCharacteristicsEvaluated);
		characteristicEvaluated.setCharacteristic(characteristic);
		characteristicEvaluated.setQuality(qualityCharacteristic);
		characteristicEvaluated.setQualityVStotal(qualityVStotal);

		return characteristicEvaluated;
	}

}
